package com.xiaoma.h5testdemo.common.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
import android.util.Log
import android.view.View
import androidx.core.content.ContextCompat
import com.xiaoma.h5testdemo.R

/**
 * author: liangjingbo
 * date: 2022/8/26
 * describe: 自定义 LoadingView， 注意要在合适时机 stopAnim()
 */
class XmLoadingView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private val TAG = this.javaClass.simpleName + "_XMTag"
    private var mCurAngle: Float = 0f
    private val mDefaultDrawableRes = R.drawable.icon_loading
    private var mDrawableRes = mDefaultDrawableRes
    private var mLoadingDrawable: Drawable?
    private val mDelayTime = 30L
    private var mIsLoading = false
    private val mInvalidateTask = { invalidate() }
    private var mCenterX = 0f
    private var mCenterY = 0f
    private val mSpeed = 360 / 1200f // 1.2s 一圈
    private val mMainHandler = Handler(Looper.getMainLooper())


    init {
        val attr = context.obtainStyledAttributes(attrs, R.styleable.XmLoadingView)
        mDrawableRes = attr.getResourceId(R.styleable.XmLoadingView_ic_loading, mDefaultDrawableRes)
        mLoadingDrawable = ContextCompat.getDrawable(context, mDrawableRes)
        attr.recycle()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mCenterX = w / 2f
        mCenterY = h / 2f
    }


    private fun checkVisible(visibility: Int) {
        if (visibility != VISIBLE) {
            stopAnim()
        } else {
            startAnim()
        }
    }

    override fun setVisibility(visibility: Int) {
        super.setVisibility(visibility)
        checkVisible(visibility)
    }


    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        stopAnim()
    }


    private fun startAnim() {
        if (mIsLoading) return
        Log.i(TAG, "startAnim() ")
        mIsLoading = true
        mCurAngle = 0f
        invalidate()
    }

    private fun stopAnim() {
        if (!mIsLoading) return
        Log.i(TAG, "stopAnim() ")
        mIsLoading = false
        mCurAngle = 0f
        mMainHandler.removeCallbacks(mInvalidateTask)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        mLoadingDrawable?.let { drawable ->
            canvas?.let { c ->
                drawLoading(c, drawable)
            }
        }
    }

    private fun drawLoading(canvas: Canvas, drawable: Drawable) {
        if (!mIsLoading) return
        val angle = mSpeed * mDelayTime
        val scaleX = width * 1.0f / drawable.intrinsicWidth
        val scaleY = height * 1.0f / drawable.intrinsicHeight
        drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
        canvas.save()
        canvas.rotate(mCurAngle, mCenterX, mCenterY)
        canvas.scale(scaleX, scaleY)
        drawable.draw(canvas)
        mCurAngle += angle
        if (mCurAngle >= 360) {
            mCurAngle = 0f
        }
        canvas.restore()
        notifyDrawing()
    }


    private fun notifyDrawing() {
        mMainHandler.postDelayed(mInvalidateTask, mDelayTime)
    }

    fun onUiModeChange() {
        mLoadingDrawable = ContextCompat.getDrawable(context, mDrawableRes)
    }
}